package com.fly.platform.base.service.serviceImp.elasticsearch

import cn.hutool.core.date.DateUtil
import cn.hutool.core.util.StrUtil
import com.fly.platform.base.mapper.elasticsearch.EsLogMapper
import com.fly.platform.base.pojo.elasticsearch.EsLog
import com.fly.platform.base.service.elasticsearch.EsLogService
import com.fly.platform.vo.SearchVo
import org.elasticsearch.index.query.QueryBuilder
import org.elasticsearch.index.query.QueryBuilders
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author Fly
 */
@Service
@Transactional
class EsLogServiceImpl : EsLogService {
    /**
     * 可选
     */
    @Autowired(required = false)
    private lateinit var esLogMapper: EsLogMapper

    override fun saveLog(esLog: EsLog): EsLog {

        return esLogMapper.save(esLog)
    }

    override fun deleteLog(id: String) {

        esLogMapper.deleteById(id)
    }

    override fun deleteAll() {

        esLogMapper.deleteAll()
    }

    override fun findByCondition(type: Int?, key: String?, searchVo: SearchVo?, pageable: Pageable?): Page<EsLog?>? {

        if (type == null && StrUtil.isBlank(key) && StrUtil.isBlank(searchVo?.startDate)) {

            // 无过滤条件获取全部
            return pageable?.let { esLogMapper.findAll(it) }

        } else if (type != null && StrUtil.isBlank(key) && StrUtil.isBlank(searchVo?.startDate)) {

            // 仅有type
            return esLogMapper.findByLogType(type, pageable)
        }

        val qb: QueryBuilder
        val qb0: QueryBuilder = QueryBuilders.termQuery("logType", type)
        val qb1: QueryBuilder = QueryBuilders.multiMatchQuery(key, "name", "requestUrl", "requestType", "requestParam", "username", "ip", "ipInfo")

        // 在有type条件下
        qb = if (StrUtil.isNotBlank(key) && StrUtil.isBlank(searchVo?.startDate) && StrUtil.isBlank(searchVo?.endDate)) {

            // 仅有key
            QueryBuilders.boolQuery().must(qb0).must(qb1)

        } else if (StrUtil.isBlank(key) && StrUtil.isNotBlank(searchVo?.startDate) && StrUtil.isNotBlank(searchVo?.endDate)) {

            // 仅有时间范围
            val start = DateUtil.parse(searchVo?.startDate).time
            val end = DateUtil.endOfDay(DateUtil.parse(searchVo?.endDate)).time
            val qb2: QueryBuilder = QueryBuilders.rangeQuery("timeMillis").gte(start).lte(end)
            QueryBuilders.boolQuery().must(qb0).must(qb2)

        } else {

            // 两者都有
            val start = DateUtil.parse(searchVo?.startDate).time
            val end = DateUtil.endOfDay(DateUtil.parse(searchVo?.endDate)).time
            val qb2: QueryBuilder = QueryBuilders.rangeQuery("timeMillis").gte(start).lte(end)
            QueryBuilders.boolQuery().must(qb0).must(qb1).must(qb2)
        }

        //多字段搜索
        return pageable?.let { esLogMapper.search(qb, it) }
    }
}